/*------------------------------------------------------------------------
//                          Project CommonLib                           //
------------------------------------------------------------------------*/

#pragma once

typedef LRESULT (__stdcall *pfMsgProc)(HWND hWnd, UINT32 msg, WPARAM wParam, LPARAM lParam);
typedef INT_PTR (__stdcall *pfDialogProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

//////////////////////////////////////////////////////////////////////////
// Entrypoint
//////////////////////////////////////////////////////////////////////////
class  IEntryPoint
{
public:
    virtual ~IEntryPoint(){};

    virtual void 			Run()=0;
    virtual void 			Terminate()=0;

protected:    
    virtual BOOL 			OnInit( const DWORD& dwX=0, const DWORD& dwY=0, const DWORD & nWorldID = 0, const DWORD & nChannelID = 0, const DWORD & nServerID = 0)=0;
    virtual BOOL 			OnUpdate()=0;
    virtual BOOL 			OnTerminate()=0;    
};


//////////////////////////////////////////////////////////////////////////
// colsole
//////////////////////////////////////////////////////////////////////////
class  EntryConsole : public IEntryPoint
{
	struct E_CREATE_SIZE
	{
		enum ECREATE_SIZE
		{
			eSCREEN_CONSOLE_BUFFER_SIZE_X = 200, 
			eSCREEN_CONSOLE_BUFFER_SIZE_Y = 5000, 
			eSCREEN_CONSOLE_WINDOW_SIZE_X = 100, 
			eSCREEN_CONSOLE_WINDOW_SIZE_Y = 60, 
			eCOMMAND_STRING_SIZE   = 0xff,
		};
	};
    

    enum E_INPUT_FLAG
    {
        eINPUT_NORMAL = -1,
        eINPUT_COMMAND = 0,
        eINPUT_COMMAND_RETURN = 1
    };

public:
    EntryConsole()
    {
        ClearCommandString();
    }
    ~EntryConsole(){}

public:        
    virtual BOOL			Initiate(const DWORD& dwX=0, const DWORD& dwY=0, const DWORD & nWorldID = 0, const DWORD & nChannelID = 0, const DWORD & nServerID = 0);    
    virtual void			Run();
    virtual void			Terminate();

    
    BOOL					ProcessConsoleEvent();
	static BOOL				ms_bRun;

protected:    
    virtual BOOL			OnInit( const DWORD& dwX=0, const DWORD& dwY=0, const DWORD & nWorldID = 0, const DWORD & nChannelID = 0, const DWORD & nServerID = 0)=0;
    virtual BOOL			OnUpdate()=0;
    virtual BOOL			OnKeyboard( UINT16)=0;
    virtual BOOL			OnTerminate()=0;
    virtual BOOL			OnCommandString( TCHAR* strCmd)=0;
    
protected:
    void 					CursorDisable();
    void 					CursorPosition();
    void 					ClearCommandString();
    void 					AddCmdString( const WORD& wKey, const TCHAR* cCmd);
    void 					InputConsoleOut(const TCHAR* pStr, const UINT16& wSize);

    BOOL 					SetMonitorSize(const DWORD& dwX, const DWORD& dwY);
    void 					CreateKeyboardThread();

    static HANDLE			ms_hKeyboard;
    static INPUT_RECORD		ms_keyBuf;
    static BOOL				ms_press;
    static int			ms_nModeInput;    
    static UINT16 			ms_nCurKey;
    static HANDLE 			ms_hIn;
    static HANDLE 			ms_hOut;    
	static TCHAR			ms_strCmd[E_CREATE_SIZE::eCOMMAND_STRING_SIZE];
    static UINT16 			ms_wCmdLinePos;

};

//////////////////////////////////////////////////////////////////////////
// window
//////////////////////////////////////////////////////////////////////////

struct TLSData
{
    LPVOID pWin;		//Pointer to CWin object for Window creation
    HHOOK  hCBTHook;	//CBT hook for Window creation
    LPVOID pMenuBar;	//Pointer to CMenuBar object
    HHOOK  hMenuHook;	//MSG hook for CMenubar
};

namespace EntryWIN32
{
    void	SetHook( LPVOID pWin);
    void	RemoveHook();
    POINT	CenterWin(HWND hWnd);

    bool	RegisterMainWindowClass(pfMsgProc fWinMsgProc, LPCTSTR strName);
}
    
enum{ eMAX_PROJECT_NAME=255 };
#include "CriticalLock.h"
class  EntryWinBase : public CriticalObj
{    
public: 
    EntryWinBase();
    virtual ~EntryWinBase();
    
    HWND					InitCreate(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, 
                                    RECT rSize, HWND hParent, pfMsgProc fWinMsgProc);

    virtual LRESULT			WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    virtual HWND			OnCreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle
								, int x, int y, int nWidth, int nHeight, HWND hParent);
    void 					Destroy();
    HWND 					GetHandle() {return m_hWnd; }

protected:   
    HWND 					m_hWnd;
    HWND 					m_hWndParent;
};

class  EntryWindow : public IEntryPoint
{
    
public: 
    EntryWindow();
    virtual ~EntryWindow();

    virtual BOOL 				Initiate(const int& startX, const int& startY, const int& widthX, const int& heightY
									,HINSTANCE hInstance, const TCHAR* strProjectName, pfMsgProc fWinMsgProc);
    virtual void 				Run();    
    virtual void 				Terminate();

    static HWND					GetHandle();
    static HINSTANCE			GetInstance();

protected:    
    
    virtual BOOL 				OnInit( const DWORD& dwX=0, const DWORD& dwY=0, const DWORD & nWorldID = 0, const DWORD & nChannelID = 0, const DWORD & nServerID = 0)=0;
    virtual BOOL 				OnUpdate()=0;
    virtual BOOL 				OnTerminate()=0;


    BOOL 						ProcessWinMsg();    
    BOOL 						CreateEx(const int& startX, const int& startY,const int& nWidth, const int& nHeight);

    BOOL 						OnCreate(const int& startX, const int& startY,const int& nWidth, const int& nHeight);

	BOOL						m_bRun;

private:
    BOOL 						CreateTls();
    void 						DestroyTls();

    TLSData						m_TLSData;
    TCHAR						m_projectName[ eMAX_PROJECT_NAME+1];

    static HWND					ms_hWnd;
    static HINSTANCE			ms_hInstance;

public:
    static DWORD				st_dwTlsIndex;// = TLS_OUT_OF_INDEXES;   
};

class  EntryDialog
{
public:
    enum E_DIALOG_STYLE
    {
        eDIALOG_TOP = 0,
        eDIALOG_CHILD = 1        
    };
public:
    EntryDialog();    
    virtual ~EntryDialog();

    void 						Create(const UINT& nResID, HINSTANCE hInstance, HWND hWndParnet
										, pfDialogProc pDialogProc, const E_DIALOG_STYLE& eStyle=eDIALOG_CHILD);
    void 						Destroy();

    INT_PTR						DoModal();
    HWND						DoModaless();    

    inline HWND					GetHandle() {return m_hWnd;}

protected:
    

    HWND 						m_hWnd;
    HWND 						m_hWndParent;
    BOOL 						m_bDoModal;
    E_DIALOG_STYLE				m_eStyle;

    HINSTANCE					m_hInstance;
    LPCTSTR						m_lpszResName;

    pfDialogProc				m_pDialogProc;
};

/*------------------------------------------------------------------------

------------------------------------------------------------------------*/
